Traditionally, computer code written in an interpreted language such as JavaScript® is not executed directly by a computer processor, and instead must be interpreted at runtime by an interpreter, runtime environment, and/or other software entity. An example of such a typical configuration is shown in FIG. 1, specifically JavaScript® 102 is executed at runtime by an interpreter 104 which interprets the JavaScript® instructions and provides corresponding machine code instructions to central processing unit (CPU) 106 for execution. An interpreted language such as JavaScript® has the advantage of being intuitive, flexible, and easy to program, but such languages may be slow to execute since the code needs to be interpreted line by line at runtime before it can be executed.
By contrast, in traditional compiled programming languages, source code typically is compiled into machine code prior to runtime, e.g., source code 116 shown being compiled into compiled code 118 at a time earlier or separate from runtime in FIG. 1. Machine code comprises very low level instructions, which are typically stored in data storage and subsequently executed directly by a processor, e.g., compiled code 120 shown being provided directly to CPU 124 in FIG. 1, with the result that source code that has been compiled to machine code typically executes on a processor more quickly or efficiently than equivalent interpreted code (e.g., JavaScript®), which requires an interpreter at runtime to execute the equivalent machine code on the processor.
More recently, scripts and other code written in interpreted languages such as JavaScript® have been precompiled to machine code executable directly by a processor, e.g., pre-compiled JavaScript® (i.e., machine code generated prior to runtime based on JavaScript®) 140 shown in FIG. 1 as being provided to CPU 144 for execution at runtime. However, the gains achieved by compiling code written in an interpreted dynamic language such as JavaScript® prior to runtime in the past have been limited by the highly flexible, dynamic, and sometimes unpredictable nature and behavior of code written in such languages. For example, in JavaScript® the variable type of a variable may be dynamically assigned or changed at runtime and, as a result, certain optimizations that could otherwise be performed on a pre-compiled version of such code, for example type-specific optimizations, cannot be performed, resulting in less optimized compiled code.